package com.lcu.wl.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lcu.wl.common.exception.SYSException;
import com.lcu.wl.common.utils.Constant;
import com.lcu.wl.common.utils.MapUtils;
import com.lcu.wl.common.utils.PageUtils;
import com.lcu.wl.common.utils.Query;
import com.lcu.wl.modules.sys.entity.User;
import com.lcu.wl.modules.sys.mapper.UserMapper;
import com.lcu.wl.modules.sys.service.IRoleService;
import com.lcu.wl.modules.sys.service.IUserRoleService;
import com.lcu.wl.modules.sys.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author wanglei
 * @since 2021-01-13
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IRoleService iRoleService;

    @Autowired
    private IUserRoleService iUserRoleService;

    @Override
    public User queryByUserName(String username) {
        return baseMapper.selectByUserName(username);
    }

    @Override
    public List<Long> queryMenuIdByUserId(Long userId) {
        return baseMapper.selectMenuIdByUserId(userId);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String username = (String)params.get("username");
        Long createUserId = (Long)params.get("createUserId");

        IPage<User> page = this.page(
                new Query<User>().getPage(params),
                new QueryWrapper<User>()
                        .like(StringUtils.isNotBlank(username),"username", username)
                        .eq(createUserId != null,"create_user_id", createUserId)
        );

        return new PageUtils(page);
    }

    @Override
    //自动事务托管，抛出异常之后，事务会自动回滚，数据不会插入到数据库
    @Transactional(rollbackFor = Exception.class)
    public void saveUser(User user) {
        user.setCreateTime(new Date());
        //sha256加密
        String salt = RandomStringUtils.randomAlphanumeric(20);
        user.setPassword(new Sha256Hash(user.getPassword(),salt).toHex());
        user.setSalt(salt);
        this.save(user);

        //检查角色是否越权
        checkRole(user);

        //保存用户与角色关系
        iUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] userIds) {
        //删除用户
        this.removeByIds(Arrays.asList(userIds));

        //删除用户和角色关系
        for (Long userId : userIds){
            iUserRoleService.removeByMap(new MapUtils().put("user_id", userId));
        }

    }

    @Override
    public String getPasswordById(Long userId) {
        return baseMapper.selectPasswordById(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserInfo(User user) {
        if (user.getPassword() != "") {
            //修改密码进行加密
            user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
        }else{
            //未修改密码时，按照原来加密的密码
            user.setPassword(this.getPasswordById(user.getUserId()));;
        }
        //更新用户信息
        this.updateById(user);
        if (user.getRoleIdList().size() != 0){
            //更新用户-角色信息
            iUserRoleService.saveOrUpdate(user.getUserId(),user.getRoleIdList());
        }
    }

    @Override
    public boolean updatePassword(Long userId, String password, String newPassword) {
        User user = new User();
        user.setPassword(newPassword);
        return this.update(user,
                new QueryWrapper<User>().eq("user_id", userId).eq("password", password));
    }

    /**
     * 检查角色是否越权
     * @param user
     */
    private void checkRole(User user) {
        if (user.getRoleIdList() == null || user.getRoleIdList().size() == 0){
            return;
        }
        //如果不是超级管理员，则需要判断用户的角色是否自己创建
        if(user.getCreateUserId() == Constant.SUPER_ADMIN){
            return;
        }

        //查询用户创建的角色列表
        List<Long> roleIdList = iRoleService.queryRoleIdList(user.getCreateUserId());

        //判断是否越权
        if(!roleIdList.containsAll(user.getRoleIdList())){
            throw new SYSException("新增用户所选角色，不是此账号创建");
        }
    }
}
